/**
 * 
 */
package org.sevaapp.security.controller;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.sevaapp.exception.SevaApplicationException;
import org.sevaapp.security.domain.Authority;
import org.sevaapp.security.domain.User;
import org.sevaapp.security.dto.UserAuthorityDto;
import org.sevaapp.security.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.Validator;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * @author spenchik
 *
 */
public abstract class BaseUserController {
	
	private static final Log log = LogFactory.getLog(BaseUserController.class);

	@Autowired
	private UserService serviceObj;
	
	@Autowired
	private org.dozer.DozerBeanMapper mapper;

	@Autowired
	private Validator validator;

	/**
	 * Validation method. Every controller should implement this method
	 * to manage the data input validation in a standard and consistent way.
	 */
	public abstract boolean validate(User inputData);

	@ModelAttribute("roles")
    public Collection<String> populateRoleTypes() {
		Collection<String> roles = new ArrayList<String>();
		roles.add("ROLE_APPLICANT");
		roles.add("ROLE_APPROVER");
		roles.add("ROLE_DISPATCHER");
		roles.add("ROLE_PHYSICIAN");
		roles.add("ROLE_LAB");
		roles.add("ROLE_ADMIN");

        return roles;
    }

	@RequestMapping("/displayAddNewUser.do")
	public String displayAddNewUser(@ModelAttribute("user") UserAuthorityDto inputData) {
		log.debug("displayAddNewUser() method called.");
		log.debug("Domain Object Data:" + inputData.toString());
		
		return "addUser";
	}

	@RequestMapping("/addUser.do")
	public String addNewUser(@ModelAttribute("user") UserAuthorityDto inputData,
			BindingResult result) throws SevaApplicationException {
		
		log.debug("addNewUser() method called.");
		log.debug("Domain Object Data:" + inputData.toString());

		validator.validate(inputData, result);
		boolean validationErrors = result.hasErrors();
		log.debug("validationErrors: " + validationErrors);
		
		if (validationErrors) {
			// Log error information
			int errCount = result.getErrorCount();
			log.debug("errCount: " + errCount);
			
			List errorList = result.getAllErrors();
			Iterator itErr = errorList.iterator();
			while (itErr.hasNext()) {
				FieldError fieldError = (FieldError)itErr.next();
				log.debug("fieldError: " + fieldError);
				
				String errMessage = fieldError.getDefaultMessage();
				log.debug("errMessage: " + errMessage);
			}
			return "addUser";
		}

		// Convert DTO to Domain Objects
		User userData = mapper.map(inputData, User.class);
		userData.setEnabled(true);

		// Set login id
		Authority role = new Authority();
		role.setLoginId(inputData.getLoginId());
		role.setRole(inputData.getRoles().get(0));

		List<Authority> roles = new ArrayList<Authority>();
		roles.add(role);
		userData.setRoles(roles);

		// Call validate method
		boolean isValidData = validate(userData);
		log.debug("isValidData=" + isValidData);
		if (isValidData) {
//			try {
				// Call add user method
				serviceObj.addNewUser(userData);
//			} catch (SevaApplicationException sse) {
//				log.error("SevaApplicationException occurred when adding the new user.", sse);
//				inputData.setException(sse);
//			}
				
//			if (inputData.getId() == null) {
//				// New record, call add method
//				serviceObj.addNewUser(userData);
//			} else {
//				// Existing record, call edit method
//				serviceObj.updateUser(userData);
//			}
			return "addUser";
		}
		return "addUser";
	}
}
